<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>放大镜光标</title>
    <style>
        * {
            padding: 0;
            margin: 0;
            box-sizing: border-box;
        }

        body {
            min-height: 100vh;
            display: grid;
            place-items: center;
            background: linear-gradient(to bottom right, #000, #0000),
            radial-gradient(circle at 0 100%, #cc338b, #284242);
            font-family: "Italiana", serif;
        }

        .card {
            position: relative;
            display: grid;
            place-items: start center;
            width: calc(100% - 2rem);
            max-width: 25rem;
            outline: 3px solid #284242;
            border-radius: 1rem;
            box-shadow: 0.5rem 0.5rem 3rem -0.75rem rgba(0 0 0 / 0.7);
            text-align: center;
            overflow: hidden;
        }

        .card > * {
            grid-area: 1/1;
        }

        img {
            max-width: 100%;
            object-fit: cover;
            transform-origin: 90% 90%;
            /*clip-path: circle(2.5rem at 82% 82%);*/
            filter: brightness(1.3);
            scale: 1.5;
        }

        /* 隐藏默认光标 */
        .card:hover {
            cursor: none;
        }

        /* 从比例放大视图: 0; */
        .card:hover > .magnifying-glass {
            scale: 1;
        }

        /* 放大镜样式 */
        .magnifying-glass {
            position: absolute;
            bottom: -4.45rem;
            left: 23.2%;
            height: 220px;
            width: 220px;
            scale: 0;
            transition: scale 0.7s ease;
            border-radius: 50%;
            background: transparent;
            box-shadow: inset 1px 2px 4px 3px rgba(255, 255, 255, 0.3),
            inset 1px 2px 3px 2px rgba(255, 255, 255, 0.05),
            inset 0 -40px 47px -18px rgba(0, 0, 0, 0.2),
            inset -5px 5px 8px 0 rgba(0, 0, 0, 0.7),
            inset -30px 15px 20px -10px rgba(0, 0, 0, 0.25),
            inset -10px 10px 30px -5px rgba(0, 0, 0, 0.7),
            inset -10px 10px 10px -5px rgba(0, 0, 0, 0.3),
            inset 50px -50px 20px -10px rgba(108, 108, 108, 0.1),
            1px 3px 8px 1px rgba(0, 0, 0, 0.4), 15px 38px 20px -30px rgba(0, 0, 0, 0.5),
            0 0 3px rgba(0, 0, 0, 0.2);
            border: 1px solid rgba(255, 255, 255, 0.15);
        }
    </style>
</head>
<body>
<div class="card">
    <!-- 图片 -->
    <img class="card-image" src="https://assets.codepen.io/4787486/man-in-suit-portrait.jpg" alt=""/>
    <!-- 放大镜 -->
    <div class="magnifying-glass"></div>
</div>

<script src='https://unpkg.co/gsap@3/dist/gsap.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
<script>
    console.clear();
    var tl = gsap.timeline({});
    tl
        .to(".split-text .char", {
            x: 0,
            opacity: 1,
            duration: 1,
            delay: 0.5,
            stagger: {
                amount: 1.5,
                from: "start"
            }
        })
        .to("img", {
                filter: "brightness(1)",
                // clipPath: "circle(25rem at 82% 82%)",
                scale: 1,
                duration: 3,
                ease: "expo.inOut"
            },
            "-=2"
        )
        /* 卡片底部的放大镜图标 */
        .to(".try-it", {
            scale: 1,
            duration: 0.5,
            ease: "back.out(4)"
        })
        .to(
            ".try-it",
            {
                rotate: 15,
                transformOrigin: "bottom left",
                duration: 0.5,
                repeat: 5,
                yoyo: true,
                ease: "none"
            },
            "+=1"
        );

    /* 放大镜 */
    $(document).ready(function () {
        var sub_width = 0;
        var sub_height = 0;
        $(".magnifying-glass").css(
            "background",
            "url('" + $(".card-image").attr("src") + "') no-repeat"
        );

        $(".card").mousemove(function (e) {
            if (!sub_width && !sub_height) {
                var image_object = new Image();
                image_object.src = $(".card-image").attr("src");
                sub_width = image_object.width;
                sub_height = image_object.height;
            } else {
                var magnify_position = $(this).offset();

                var mx = e.pageX - magnify_position.left;
                var my = e.pageY - magnify_position.top;

                if (mx < $(this).width() && my < $(this).height() && mx > 0 && my > 0) {
                    $(".magnifying-glass").fadeIn(100);
                } else {
                    $(".magnifying-glass").fadeOut(100);
                }
                if ($(".magnifying-glass").is(":visible")) {
                    var rx =
                        Math.round(
                            (mx / $(".card-image").width()) * sub_width -
                            $(".magnifying-glass").width() / 3
                        ) * -1;
                    var ry =
                        Math.round(
                            (my / $(".card-image").height()) * sub_height -
                            $(".magnifying-glass").height() / 3
                        ) * -1;

                    var bgp = rx + "px " + ry + "px";

                    var px = mx - $(".magnifying-glass").width() / 2.5;
                    var py = my - $(".magnifying-glass").height() / 2.5;

                    $(".magnifying-glass").css({left: px, top: py, backgroundPosition: bgp});
                }
            }
        });
    });
</script>
</body>
</html>
